package com.itany.corejava.code13_jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author MissChen
 * @version 1.0
 * @date 2023 年12月13日 10:09
 */
public class Test09_多表查询 {
    public static void main(String[] args) {
        try {
           // List<Emp> emps= queryAll();
           // for(Emp e:emps){
           //     System.out.println(e);
           // }

            Dept dept=queryDeptById(9);
            System.out.println(dept);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
    }

    // 多对一查询
    // 查询所有员工以及员工所属的部门信息
    public static List<Emp> queryAll() throws DataAccessException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<Emp> emps = new ArrayList<>();
        try {
            conn = JDBCUtil.getConnection();
            String sql = new StringBuffer()
                    .append(" select e.id,e.name,e.salary,d.id 'd.id',d.name 'd.name',d.remark ")
                    .append(" from t_emp e ")
                    .append(" left join t_dept d ")
                    .append(" on e.dept_id=d.id ")
                    .toString();
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                Emp emp = new Emp();
                emp.setId(rs.getInt("id"));
                emp.setName(rs.getString("name"));
                emp.setSalary(rs.getDouble("salary"));

                //准备Dept的实例对象，将结果集中的数据进行映射进来
                Dept dept = new Dept();
                dept.setId(rs.getInt("d.id"));
                dept.setName(rs.getString("d.name"));
                dept.setRemark(rs.getString("remark"));

                //员工实例存在一个Dept类型的属性，该属性就是部门对象
                emp.setDept(dept);

                //每映射一行数据，就生成一个Emp对象，添加到集合中去
                emps.add(emp);

            }


        } catch (DataAccessException e) {
            e.printStackTrace();
            throw e;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DataAccessException("访问数据库失败");
        } finally {
            JDBCUtil.close(conn,ps,rs);
        }

        return  emps;
    }

    // 一对多关系
    // 根据部门编号查询部门以及该部门下的所有员工信息，一个参数
    public static Dept queryDeptById(Integer id) throws DataAccessException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Dept dept=null;
        try {
            conn=JDBCUtil.getConnection();
            String sql=new StringBuffer()
                    .append(" select d.id,d.name,d.remark,e.id,e.name,e.salary ")
                    .append(" from t_dept d ")
                    .append(" left join t_emp e ")
                    .append(" on d.id=e.dept_id ")
                    .append(" where d.id=? ")
                    .toString();
            ps=conn.prepareStatement(sql);
            ps.setInt(1,id);
            rs=ps.executeQuery();
            while(rs.next()){
                //一对多映射,第一次会new Dept(),第二次、第三次....不会再new Dept()，因为进不来判断
                if(dept==null){
                    dept=new Dept();
                    dept.setId(rs.getInt("d.id"));
                    dept.setName(rs.getString("d.name"));
                    dept.setRemark(rs.getString("d.remark"));

                }

                Emp emp=new Emp();
                emp.setId(rs.getInt("e.id"));
                emp.setName(rs.getString("e.name"));
                emp.setSalary(rs.getDouble("e.salary"));

                //将对应的员工添加到对应的对象集合中去
                dept.addEmp(emp);


            }




        } catch (DataAccessException e) {
            e.printStackTrace();
            throw  e;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new DataAccessException("数据库访问失败");
        } finally {
            JDBCUtil.close(conn,ps,rs);
        }
        return dept;
    }


}
